package com.mainbo.modular.system.service.impl;

import com.mainbo.core.shiro.SessionKey;
import com.mainbo.core.shiro.ShiroKit;
import com.mainbo.modular.jms.JmsService;
import com.mainbo.modular.jms.MessageTypes;
import com.mainbo.modular.jms.model.SchoolYearMessage;
import com.mainbo.modular.jms.model.TermMessage;
import com.mainbo.modular.jms.model.TermVo;
import com.mainbo.modular.system.dao.PtConfigMapper;
import com.mainbo.modular.system.model.PtAccount;
import com.mainbo.modular.system.model.PtConfig;
import com.mainbo.modular.system.model.meta.ConfigConstants;
import com.mainbo.modular.system.model.meta.MetaUtils;
import com.mainbo.modular.system.model.meta.vo.Meta;
import com.mainbo.modular.system.model.vo.SchoolYearVo;
import com.mainbo.modular.system.service.IPtConfigService;
import com.mainbo.modular.system.service.IPtSchoolYearTermManageService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @Author xww
 * @Description //TODO
 * @Date 2020/3/9   16:08
 **/
@Service
public class PtSchoolYearTermManageServiceImpl implements IPtSchoolYearTermManageService {

    private static final Logger logger = LoggerFactory
            .getLogger(PtSchoolYearTermManageServiceImpl.class);
    private static final String HYPHEN = "-";
    @Resource
    private IPtConfigService configService;
    @Resource
    private JmsService jmsService;
    @Resource
    private PtConfigMapper configMapper;
    @Override
    public List<SchoolYearVo> getSchoolYearAndTermByOrg(String orgId) {
        List<Meta> schoolYearWithOrg = MetaUtils.getSchoolYearProvider()
                .getSchoolYearWithOrg(orgId);
        return parseSchoolYearAndTerm(schoolYearWithOrg);
    }

    @Override
    public List<SchoolYearVo> getSchoolYearAndTermByArea(Integer areaId) {
        List<Meta> schoolYearWithArea = MetaUtils.getSchoolYearProvider()
                .getSchoolYearWithArea(areaId);
        return parseSchoolYearAndTerm(schoolYearWithArea);
    }

    @Override
    public void saveSchoolYear(SchoolYearVo vo) {
        PtAccount account = ShiroKit.getSessionAttr(SessionKey.CURRENT_USER);// 当前登录账号
        PtConfig model = new PtConfig();
        model.setCode(ConfigConstants.SCHOOLYEAR_CODE);
        if (StringUtils.isNotEmpty(vo.getOrgId())) {
            model.setType(ConfigConstants.ORG_TYPE);
            model.setOrgId(vo.getOrgId());

        } else if (vo.getAreaId() != null) {
            model.setType(ConfigConstants.AREA_TYPE);
            model.setAreaId(vo.getAreaId());
        }
        model.setCrtDttm(new Date());
        model.setCrtId(account.getUserInfo().getId());
        model.setName(vo.getName());
        model.setValue(vo.getStartTime() + HYPHEN + vo.getEndTime());
        // 借用学段表示学期的当前年份
        String[] split = vo.getStartTime().split("\\.");
        model.setPhase(Integer.valueOf(split[0]));
        model.setEnable(1);
        boolean config= configService.insert(model);
        if (config){
            vo.setId(model.getId());
            vo.setCrtId(model.getCrtId());
            vo.setCrtDttm(model.getCrtDttm());
            jmsService.sendMessage(new SchoolYearMessage(MessageTypes.SCHOOLYEAR_ADD.name(), vo));
        }
    }

    @Override
    public void updateSchoolYear(SchoolYearVo vo) {
        PtConfig model = new PtConfig();
        model.setId(vo.getId());
        model.setName(vo.getName());
        model.setValue(vo.getStartTime() + HYPHEN + vo.getEndTime());
        String[] split = vo.getStartTime().split("\\.");
        model.setPhase(Integer.valueOf(split[0]).intValue() + 1);
        boolean flag= configService.updateById(model);
        if (flag){
            jmsService.sendMessage(new SchoolYearMessage(MessageTypes.SCHOOLYEAR_UPDATE.name(), vo));
        }
    }

    @Override
    public List<SchoolYearVo> getSchoolTerm(Integer schoolYearId) {
        List<Meta> term = MetaUtils.getSchoolYearProvider().getTerm(schoolYearId);
        List<SchoolYearVo> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(term)) {
            return list;
        }
        for (Meta meta : term) {
            try {
                list.add(parseTerm(meta));
            } catch (Exception e) {
                logger.warn("处理学期数据失败，metaId:{}", meta.getId());
                logger.error("", e);
            }
        }
        return list;
    }

    @Override
    public SchoolYearVo getTerm(Integer termId) {
        Meta meta = MetaUtils.getMeta(termId);
        SchoolYearVo parseTerm = null;
        try {
            parseTerm = parseTerm(meta);
        } catch (Exception e) {
            logger.error("解析学期错误，学期ID：{}", meta.getId());
        }

        return parseTerm;
    }

    @Override
    public void updateSchoolTerm(SchoolYearVo vo) {
        PtConfig config = new PtConfig();
        config.setId(vo.getTermId());
        config.setCode(ConfigConstants.TERM_CODE);
        config.setType(ConfigConstants.ORG_TYPE);
        config.setPhase(vo.getId());
        if (vo.getSysTermId() != null) {
            config.setDomain(String.valueOf(vo.getSysTermId()));
            config.setName(MetaUtils.getMeta(vo.getSysTermId()).getName());
        }

        String value = vo.getWeeks().intValue() + HYPHEN + vo.getTermStartTime()
                + HYPHEN + vo.getTermEndTime() + HYPHEN + vo.getTeachStartTime()
                + HYPHEN + vo.getTeachEndTime();
        config.setValue(value);
        config.setEnable(1);
        boolean flag= configService.updateById(config);
        if (flag){
            TermVo termVo=new TermVo();
            termVo.setId(vo.getTermId());
            termVo.setTeachStartTime(vo.getTeachStartTime());
            termVo.setTeachEndTime(vo.getTeachEndTime());
            termVo.setTermStartTime(vo.getTermStartTime());
            termVo.setTermEndTime(vo.getTermEndTime());
            termVo.setWeeks(vo.getWeeks());
            jmsService.sendMessage(new TermMessage(MessageTypes.TERM_UPDATE.name(), termVo));
        }
    }

    @Override
    public boolean saveSchoolTerm(SchoolYearVo vo) {
        PtAccount account =ShiroKit.getSessionAttr(SessionKey.CURRENT_USER);// 当前登录账号
        PtConfig config = new PtConfig();

        config.setCode(ConfigConstants.TERM_CODE);
        config.setType(ConfigConstants.ORG_TYPE);
        config.setPhase(vo.getId());
        config.setOrgId(vo.getOrgId());
        config.setDomain(vo.getSysTermId().toString());
        PtConfig cfg = configMapper.selectOne(config);

        if (cfg != null) {
            return false;
        }
        config.setName(MetaUtils.getMeta(vo.getSysTermId()).getName());
        String value = vo.getWeeks().intValue() + HYPHEN + vo.getTermStartTime()
                + HYPHEN + vo.getTermEndTime() + HYPHEN + vo.getTeachStartTime()
                + HYPHEN + vo.getTeachEndTime();
        config.setValue(value);
        config.setEnable(1);
        config.setCrtDttm(new Date());
        config.setCrtId(account.getUserInfo().getId());
        boolean flag=configService.insert(config);
        if (flag){
            TermVo termVo=new TermVo();
            termVo.setId(config.getId());
            termVo.setCrtId(config.getCrtId());
            termVo.setCrtDttm(config.getCrtDttm());
            termVo.setName(config.getName());
            termVo.setTermStartTime(vo.getTermStartTime());
            termVo.setTermEndTime(vo.getTermEndTime());
            termVo.setTeachStartTime(vo.getTeachStartTime());
            termVo.setTeachEndTime(vo.getTeachEndTime());
            termVo.setWeeks(vo.getWeeks());
            termVo.setSchoolYear(vo.getName());
            termVo.setOrgId(vo.getOrgId());
            jmsService.sendMessage(new TermMessage(MessageTypes.TERM_ADD.name(), termVo));
        }
        return true;
    }

    @Override
    public List<Meta> getSchoolYear(String orgId) {
        return MetaUtils.getSchoolYearProvider().getSchoolYearWithOrg(orgId);
    }

    /**
     * 查找学年下的学期 学年的第一个学期会设置学年信息 其余的学期不会设置学年信息 页面上循环添加学年学期时表格rowspan显示
     *
     * @param metaList
     *          list of 学期
     * @return list of 学年
     */
    protected List<SchoolYearVo> parseSchoolYearAndTerm(List<Meta> metaList) {
        List<SchoolYearVo> list = new ArrayList<>();
        for (Meta meta : metaList) {
            SchoolYearVo yearvo = parseTerm(meta);
            List<Meta> terms = MetaUtils.getSchoolYearProvider()
                    .getTerm(meta.getId());
            if (CollectionUtils.isEmpty(terms)) {
                SchoolYearVo scVo = new SchoolYearVo();
                scVo.setId(meta.getId());
                scVo.setName(meta.getName());
                String[] times = meta.getValue().split(HYPHEN);
                scVo.setStartTime(times[0]);
                scVo.setEndTime(times[1]);
                scVo.setName(scVo.getName()+"("+times[0]+"-"+times[1]+")");
                list.add(scVo);
            } else {
                for (int i = 0; i < terms.size(); i++) {
                    SchoolYearVo term = parseTerm(terms.get(i));
                    term.setName(yearvo.getName());
                    if (i == 0) {
                        term.setTermSize(terms.size());
                        term.setId(yearvo.getId());
                        term.setStartTime(yearvo.getStartTime());
                        term.setEndTime(yearvo.getEndTime());
                    }

                    list.add(term);
                }

            }
        }
        return list;
    }

    protected SchoolYearVo parseTerm(Meta meta) {
        SchoolYearVo scVo = new SchoolYearVo();
        PtConfig config = (PtConfig) meta;
        String[] times = meta.getValue().split(HYPHEN);
        switch (config.getCode()) {
            case ConfigConstants.SCHOOLYEAR_CODE:
                scVo.setId(config.getId());
                scVo.setName(config.getName());
                scVo.setStartTime(times[0]);
                scVo.setEndTime(times[1]);
                scVo.setName(scVo.getName()+"("+times[0]+"-"+times[1]+")");
                break;

            case ConfigConstants.TERM_CODE:
                scVo.setTermId(config.getId());
                scVo.setTermName(config.getName());
                scVo.setWeeks(Integer.valueOf(times[0]));
                scVo.setTermStartTime(times[1]);
                scVo.setTermEndTime(times[2]);
                scVo.setTeachStartTime(times[3]);
                scVo.setTeachEndTime(times[4]);
                scVo.setSysTermId(StringUtils.isNotBlank(config.getDomain()) ? Integer
                        .valueOf(config.getDomain()) : null);
                scVo.setTermScope(scVo.getTermStartTime().concat("-").concat(scVo.getTermEndTime()));
                scVo.setTeacherScope(scVo.getTeachStartTime().concat("-").concat(scVo.getTeachEndTime()));
                break;
            default:
                break;
        }
        return scVo;
    }
}
